#ifndef H_miniwin_H
#define H_miniwin_H

#define  STRICT   1
#define  NOMINMAX 1
#define  WIN32_LEAN_AND_MEAN

#if defined(_WIN32) && !defined(WIN32)
# define WIN32
#endif

#if defined(_UNICODE) && !defined(UNICODE)
# define UNICODE
#endif
#if defined(UNICODE) && !defined(_UNICODE)
# define _UNICODE
#endif

#if !defined(_WIN32_WINNT) || _WIN32_WINNT < 0x601
# undef  _WIN32_WINNT
# define _WIN32_WINNT 0x601
#endif

#if _MSC_VER <= 1200
# pragma warning( disable : 4514 ) /* unreferenced inline function removed */
# pragma warning( disable : 4710 ) /* function not inlined */
# pragma warning( disable : 4711 ) /* function inlined */
# pragma warning( push )
# pragma warning( disable : 4305 )
#endif

#include <windows.h>
#include <tchar.h>

#if _MSC_VER <= 1200
# pragma warning( pop )
#endif

#define dim(array)  (sizeof(array) / sizeof(array[0]))
#define idim(array) ((int)(dim(array)))

#define size_of(struc, item) (sizeof((struc *)0)->item)
#define isize_of(struc, item) ((int)size_of(struc, item))

#if !defined(offsetof)
# define offsetof(s,m) ((size_t)&reinterpret_cast<const volatile char&>((((s *)16)->m)) - 16)
#else
# define offsetof(s,m) ((size_t)&(((s *)0)->m))
#endif 
#define offset_of(struc, item) offsetof(struc, item)
#define ioffset_of(struc, item) ((int)offset_of(struc, item))

namespace Win
{
   void panic(const char *errstr, int exit_code = 99);

   void* alloc(int size);
   void  alloc(void* &pbuff, int size);

   char  *strdup( const char  *str );
   WCHAR *strdup( const WCHAR *str );

   int wtoa( const WCHAR *src, char *dst, int msize, UINT cp=CP_ACP );
   int atow( const char *src, WCHAR *dst, int msize, UINT cp=CP_ACP );
   int wtoa( const WCHAR *src, int nw, char *dst, int msize, UINT cp=CP_ACP );
   int atow( const char *src, int na, WCHAR *dst, int msize, UINT cp=CP_ACP );

   const char *vers(const char *prog);
   void init();
   void cleanup();

   bool geterr( WCHAR *text, int msize );

   bool exists( const WCHAR *name, DWORD attr = 0 );

   void bzero( void *pbuf, size_t nb );
   void bset ( void *pbuf, int value, size_t nb );
   int  bcmp ( const void *pbuf1, const void *pbuf2, size_t nb );
   void bmov ( void *dest, const void *source, size_t nb );
   void bswap( WCHAR *dest, int nw, const WCHAR *src = 0);

   extern HMODULE hnt, hkern, hadv, hrpc;
   extern int os_version;

   // file/directory scan
   //
   struct SearchContext;
   typedef bool (*CheckFunc)( const WIN32_FIND_DATAW *ff, SearchContext *ctx );
   //
   struct SearchContext
   {
      WCHAR *path;
      int cb_path;
      int nb_path;

      CheckFunc check_one;

      union {
         const void  *pv;
         const WCHAR *pw;
         const BY_HANDLE_FILE_INFORMATION *fi;
      } p1;
      union {
         const void  *pv;
         const WCHAR *orig;
      } p2;

      DWORD found;
      bool done;
      bool ignore;
   };
   //
   void init_search_context( SearchContext *ctx,
      WCHAR *pw, int cb, CheckFunc pf, const void *p1=NULL, const void *p2=NULL
   );
   //
   int search_files( SearchContext *ctx,
      const WCHAR *base, const WCHAR *mask, bool recursive
   );
}

#endif /* H_miniwin_H */
